package controllers;

import play.*;
import play.mvc.*;
import play.mvc.results.*;

import java.util.*;

import javax.mail.Session;

import org.json.simple.JSONObject;

import com.google.gson.Gson;

import models.*;

public class Game extends Controller {
	
	final static int ROW_NUMBER = 8;
	final static int COLUMN_NUMBER = 8;
	final static int ITEM_NUMBER = 6;
	
	static int[][] boardItems = new int[ROW_NUMBER][COLUMN_NUMBER];
	static int[] finishItems = new int[ITEM_NUMBER + 1];
	static boolean[][] tmp_item_list = new boolean[ROW_NUMBER][COLUMN_NUMBER];
	
    public static void index() {
        render();
    }
    
    public static void createData(){
    	
    	Board board = new Board();
    	
    	Gson gson = new Gson();
    	String result = gson.toJson(board);
    	
        session.put("board", result);
        
        renderText(result);
    }

    /*
     * Move item và check xem nước đó có ăn hay không
     * Return
     * 		- result.status: có ăn hay không
     * 		- result.data: list item bàn cờ mới, đã lấp đầy những lỗ trống
     * 		- result.tmpData : bàn cờ đánh đấu true, false đánh dấu những quân ăn
     */
	public static void moveItem(int row, int column, int new_row, int new_column)
	{
		String boardJson = session.get("board");
		
		Gson gson = new Gson();
		Board board = gson.fromJson(boardJson, Board.class);
		boardItems = board.itemList;
		
		System.out.println("Server: move item (" + row + "," + column +") -> (" + new_row + ", "+ new_column + ")");
		
		int item = boardItems[row][column];
		int new_item = boardItems[new_row][new_column];
		
		boardItems[row][column] = new_item;
		boardItems[new_row][new_column] = item;
			
		board.status = verifyAllItem();
		
		if(board.status)		
		{
			boardItems = createNewItems(boardItems);		
		}
		else // Nếu move ko ăn, revert lại vị trí 2 quân cờ
		{
			boardItems[row][column] = item;
			boardItems[new_row][new_column] = new_item;
		}
		
		board.itemList = boardItems;
		board.tmpItemList = tmp_item_list;
		board.finishItems = finishItems;
		
		boardJson = gson.toJson(board);
		
		session.put("board", boardJson);
		
		renderText(boardJson);
	}
	
	/*
     * Check all items
     * Return
     * 		- result.status: có ăn hay không
     * 		- result.data: list item bàn cờ mới, đã lấp đầy những lỗ trống
     * 		- result.tmpData : bàn cờ đánh đấu true, false đánh dấu những quân ăn
     */
	public static void checkAllItems()
	{
		String boardJson = session.get("board");
		
		//System.out.println("Data json: " + boardJson);
		
		Gson gson = new Gson();
		Board board = gson.fromJson(boardJson, Board.class);
		boardItems = board.itemList;
		
		board.status = verifyAllItem();
		
		if(board.status)		
		{
			boardItems = createNewItems(boardItems);		
		}
		
		board.itemList = boardItems;
		board.tmpItemList = tmp_item_list;
		board.finishItems = finishItems;
		
		boardJson = gson.toJson(board);
		
		session.put("board", boardJson);
		
		renderText(boardJson);
	}
	
	/*
	 * Tạo dữ liệu item cho những vị trí trống
	 */
	public static int[][] createNewItems(int[][] data) {
		
		for (int i = ROW_NUMBER-1; i >= 0 ; i--) {
			for (int j = 0 ; j < COLUMN_NUMBER; j++) {
				if (data[i][j] == 0) {
					// look above for an icon to fill the hole
					int k = 1;
					while((i - k) >= 0 && data[i-k][j] == 0) {
						k++;
					}
					
					// Random quân tại vị trí trống	
					if ((i - k) < 0) {  
						// no icon found above : create random new icon
						int randomValue = Board.randomInt(1, ITEM_NUMBER);
	      
						data[i][j] = randomValue;
						
						System.out.println("add new item to (" + i + ", " + j + ") => " + data[i][j]);
					} 
					else 	// Chuyển quân trên xuống quân dưới
					{
						data[i][j] = data[i-k][j];
						data[i-k][j] = 0;
					}
					
				}
			}
		}
		
		return data;
	};
	
	/*
	 * Check tất cả các quân cờ xem có quân nào ăn được hay không. Return true | false
	 */
	public static boolean verifyAllItem() {
		
		boolean result = false;
		
		finishItems = new int[ITEM_NUMBER + 1];
		tmp_item_list = new boolean[ROW_NUMBER][COLUMN_NUMBER];
		
		// Reset finishItems
		for (int i = 0; i <= ITEM_NUMBER; i++) {
			finishItems[i] = 0;
		}
		
		// Reset tmp_item_list
		for (int i = 0; i < ROW_NUMBER; i++) {
			for (int j = 0; j < COLUMN_NUMBER; j++) {
				tmp_item_list[i][j] = false;
			}
		}
		
		// verify từng item từ (0,0) -> (7,7)
		for (int i = 0; i < ROW_NUMBER; i++) {
			for (int j = 0 ; j < COLUMN_NUMBER; j++) {
				if (verifyItem(i, j)) {
					result = true;
				}
			}
		}
		
		// Set value = 0 cho những item được ăn
		for (int i = 0; i < ROW_NUMBER; i++) {
			for (int j = 0 ; j < COLUMN_NUMBER; j++) {
				if (tmp_item_list[i][j]) {   
					finishItems[boardItems[i][j]]++;
					boardItems[i][j] = 0;
				}          
			}
		}
		
		System.out.println("Server: check all item => " + result);
		
		return result;
	};
	
	/*
	 * Check quân cờ tại vị trí (row, column) xem có ăn được hay không
	 * Result :
	 * 		- true : nếu ăn được
	 * 		- false: nếu không ăn được
	 */
	public static boolean verifyItem(int row, int column) {
		boolean result = false;
	  
		int itemValue = boardItems[row][column];
	  
		int vertical_item_num = 1;
		int horizontal_item_num = 1;
		int i;
		
		// Check dọc xuống
		if (!tmp_item_list[row][column]) {
			i = 1;
			while(row + i < COLUMN_NUMBER && boardItems[row+i][column] == itemValue && !tmp_item_list[row+i][column]) {
				vertical_item_num++;
				i++;
			}
	    
			if (vertical_item_num >= 3) {	// Nếu ăn theo hàng dọc (quân ăn >= 3)
				result = true;
				
				tmp_item_list[row][column] = true;
		      
				// Đánh dấu những quân bị ăn vào mảng Server.tmp_item_list
				i = 1;
				while(row+i < COLUMN_NUMBER && boardItems[row+i][column] == itemValue) {
					tmp_item_list[row+i][column] = true;
					i++;
				} 
			}
		}

		// Check ngang
		if (!tmp_item_list[row][column]) {
			i = 1;
	    
			while(column + i < ROW_NUMBER && boardItems[row][column + i] == itemValue && !tmp_item_list[row][column + i]) {
				horizontal_item_num++;
				
				i++;
			}

			if (horizontal_item_num >= 3) {	// Nếu ăn theo hàng ngang (quân ăn >= 3)
				result = true;

				tmp_item_list[row][column] = true;
	      
				// right
				i = 1;
				while(column+i < ROW_NUMBER && boardItems[row][column+i] == itemValue) {
		    	  // VH add
					tmp_item_list[row][column+i] = true;
					i++;
				} 
			}
		} 
	  
		//System.out.println("check_item(" + row + ", " + column + ") => " + result);
		return result;
	}
}